/*
 * thread.cpp
 *
 *  Created on: 2008-8-13
 *      Author: fanliangliang
 */

#include "bits/thread.h"
#include <pthread.h>
#include <unistd.h>

BEGIN_NAMESPACE_TOXIC

void* Thread::start_routine(void* arg) {
	Thread* thread = static_cast<Thread*>(arg);
	if (thread->_target != 0) {
		thread->_target->run();
	}
	else {
		thread->run();
	}
	return 0;
}

Thread::Thread()
:_target(0)
,_tid(0)
,_handle(0) {

}

Thread::~Thread() {
	delete _target;
}

void Thread::run() {

}

void Thread::start() {
	if (_tid == 0) {
		//pthread_attr_t attr;
		//pthread_attr_init(&attr);
		//pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
		int ret = pthread_create(reinterpret_cast<pthread_t*>(&_tid), 0, start_routine, this);
		//pthread_attr_destroy(&attr);
        if (ret != 0) {
        	throw ThreadException("'pthread_create()' failed");
        }
	}
}

void Thread::join() {
	if (_tid != 0) {
		int ret = pthread_join(_tid, 0);
        if (ret != 0) {
            throw ThreadException("'pthread_join()' failed");
        } else {
        	_tid = 0;
        }
	}
}

size_t Thread::id() const {
	return _tid;
}

void Thread::yield() {
	pthread_yield();
}

void Thread::sleep(unsigned long ms) {
	::usleep(1000 * ms);
}

size_t Thread::self() {
	return pthread_self();
}

bool operator==(const Thread& lhs, const Thread& rhs) {
	return pthread_equal(lhs.id(), rhs.id()) != 0;
}

bool operator!=(const Thread& lhs, const Thread& rhs) {
	return pthread_equal(lhs.id(), rhs.id()) == 0;
}

END_NAMESPACE_TOXIC
